package com.leyou.trade.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.auth.utils.UserContext;
import com.leyou.common.exception.LyException;
import com.leyou.item.clients.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.trade.dto.OrderDTO;
import com.leyou.trade.entity.Order;
import com.leyou.trade.entity.OrderDetail;
import com.leyou.trade.entity.OrderLogistics;
import com.leyou.trade.mapper.OrderMapper;
import com.leyou.trade.service.CartService;
import com.leyou.trade.service.OrderDetailService;
import com.leyou.trade.service.OrderLogiisticsService;
import com.leyou.trade.service.OrderService;
import com.leyou.user.client.UserCilent;
import com.leyou.user.dto.AddressDTO;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

import static com.leyou.common.constants.MQConstants.ExchangeConstants.ORDER_EXCHANGE_NAME;
import static com.leyou.common.constants.MQConstants.RoutingKeyConstants.EVICT_ORDER_KEY;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private OrderDetailService detailService;
    @Autowired
    private OrderLogiisticsService logiisticsService;
    @Autowired
    private ItemClient itemClient;
    @Autowired
    private UserCilent userClient;
    @Autowired
    private CartService cartService;
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    @Transactional
    public Long createOrder(OrderDTO orderDTO) {
        Order order = new Order();
        //订单状态未付款
        order.setStatus(1);
        //用户id
        order.setUserId(UserContext.getUser().getId());
        //包邮
        order.setPostFee(0L);
        //支付方式
        order.setPaymentType(orderDTO.getPaymentType());

        //实际付款
        Map<Long, Integer> cartsMap = orderDTO.getCarts();
        if (CollectionUtils.isEmpty(cartsMap)) {
            throw new LyException(400, "下单失败");
        }
        ArrayList<Long> longs = new ArrayList<>(cartsMap.keySet());
        List<SkuDTO> skuDTOS = this.itemClient.querySkuBylist(longs);
        if (skuDTOS == null) {
            throw new LyException(400, "参数有误");
        }

        long totalFe = 0;
        for (SkuDTO skuDTO : skuDTOS) {
            Long skuId = skuDTO.getId();
            totalFe += skuDTO.getPrice() * cartsMap.get(skuId);
        }
        //支付价格
        order.setTotalFee(totalFe);
        order.setActualFee(totalFe);
        //添加订单
        this.save(order);
        //订单详情页(数据库)
        List<OrderDetail> orderCollects = skuDTOS.stream().map(skuDTO -> {
            OrderDetail orderDetail = new OrderDetail();
            //skuDto=>OrderDetail
            orderDetail.setOrderId(order.getOrderId());
            orderDetail.setSkuId(skuDTO.getId());
            orderDetail.setNum(cartsMap.get(skuDTO.getId()));
            orderDetail.setTitle(skuDTO.getTitle());
            orderDetail.setSpec(skuDTO.getSpecialSpec());
            orderDetail.setImage(StringUtils.substringBefore(skuDTO.getImages(), ","));
            orderDetail.setPrice(skuDTO.getPrice());
            return orderDetail;
        }).collect(Collectors.toList());
        //添加订单详情
        this.detailService.saveBatch(orderCollects);
        //用户地址对象
        AddressDTO addressDTO = this.userClient.queryAddressById(UserContext.getUser().getId(), orderDTO.getAddressId());
        //订单物流信息
        OrderLogistics orderLogistics = new OrderLogistics();
        //订单id
        orderLogistics.setOrderId(order.getOrderId());
        //物流信息
        BeanUtils.copyProperties(addressDTO, orderLogistics);
        //添加物流信息
        this.logiisticsService.save(orderLogistics);
        //批量削减库存
        this.itemClient.minusStock(cartsMap);
        //结算业务走到最后需要删除已经结算商品
        amqpTemplate.convertAndSend(ORDER_EXCHANGE_NAME, EVICT_ORDER_KEY, order.getOrderId());
        return order.getOrderId();
    }

    @Override
    public void clearOrder() {

        DateTime dateTime = DateTime.now().minusHours(24);

        //TODO 要先查询，订单，确定要关闭了，再关闭，并且还原库存

        //先查，已失效订单
        Date deadLine = DateTime.now().minusHours(24).toDate();

        List<Order> evictOrders = this.query().eq("status", 1)
                .lt("create_time", deadLine).list();

        if (CollectionUtils.isEmpty(evictOrders)) {
            return;
        }

        //查需要被还原的库存（订单详情）

        //select * from tb_order_detail where order_id in (xxx,xxx,xxx);
        List<OrderDetail> orderDetails = this.detailService.query()
                .in("order_id",
                        evictOrders
                                .stream()
                                .map(Order::getOrderId)
                                .collect(Collectors.toList()))
                .list();

        //要还原的商品id以及num数量对应关系
        Map<Long, Integer> cartsMap = new HashMap<>();

        orderDetails.forEach(orderDetail -> {
            Long skuId = orderDetail.getSkuId();
            Integer num = orderDetail.getNum();

            //存在改数量，不存在，直接添加
            if (cartsMap.containsKey(skuId)) {
                cartsMap.put(skuId, cartsMap.get(skuId) + num);
            } else {
                cartsMap.put(skuId, num);
            }
        });

        evictOrders.forEach(evictOrder -> {
            evictOrder.setStatus(5);
            evictOrder.setCloseTime(new Date());
        });

        //批量修改
        this.updateBatchById(evictOrders);


        //TODO 考虑数据量，分批次处理，分布式事务
        this.itemClient.plusStock(cartsMap);

        //update tb_order set status = 5,close_time = now() where status = 1 and crate_time < deadLine;
//        update()
//                .set("status",5)
//                .set("close_time",new Date())
//                .eq("status",1)
//                .lt("create_time",deadLine)
//                .update();


    }

    @Override
    public void evictOrderIfNecessary(Long orderId) {
        //查询订单
        Order order = this.getById(orderId);
        //未支付
        if (1 == order.getStatus()) {
            //查询订单详情
            List<OrderDetail> orderDetails = this.detailService.query().eq("order_id", orderId).list();
            //要还原的商品id以及num数量对应关系
            Map<Long, Integer> cartsMap = new HashMap<>();

            orderDetails.forEach(orderDetail -> {
                Long skuId = orderDetail.getSkuId();
                Integer num = orderDetail.getNum();

                //存在改数量，不存在，直接添加
                if (cartsMap.containsKey(skuId)) {
                    cartsMap.put(skuId, cartsMap.get(skuId) + num);
                } else {
                    cartsMap.put(skuId, num);
                }
            });
            order.setStatus(5);
            order.setCloseTime(new Date());
            this.updateById(order);
            this.itemClient.plusStock(cartsMap);
        }


    }
}